﻿using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.BTB_StaffUsers;
using Coldairarrow.Entity.UserDTO;
using Coldairarrow.IBusiness;
using Coldairarrow.IBusiness.BTB_StaffUsers;
using Coldairarrow.Util;
using Coldairarrow.Util.Config;
using Coldairarrow.Util.DTO;
using Coldairarrow.Util.ERQcde;
using Coldairarrow.Util.lib;
using EFCore.Sharding;
using LinqKit;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.DependencyInjection;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.BTB_StaffUsers
{
    public class BTB_StaffUserBusiness : BaseBusiness<BTB_StaffUser>, IBTB_StaffUserBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        readonly IDbAccessor _db;
        readonly IServiceProvider _serviceProvider;
        readonly IConfigsService _configsService;
        private const string Token = "evalu211101dl";

        public BTB_StaffUserBusiness(IDbAccessor db, IServiceProvider serviceProvider, IConfigsService configsService, IOperator @operator)
            : base(db)
        {
            _serviceProvider = serviceProvider;
            _configsService = configsService;
            _operator = @operator;
            _db = db;
        }

        #region 外部接口

        public async Task<PageResult<BTB_StaffUser>> GetDataListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<BTB_StaffUser>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<BTB_StaffUser, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            return await q.Where(where).GetPageResultAsync(input);
        }

        public async Task<PageResult<BTB_StaffUser>> GetBackStaffUserListAsync(PageInput<ConditionDTO> input)
        {
            var q = GetIQueryable();
            var where = LinqHelper.True<BTB_StaffUser>();
            var search = input.Search;

            //筛选
            if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            {
                var newWhere = DynamicExpressionParser.ParseLambda<BTB_StaffUser, bool>(
                    ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
                where = where.And(newWhere);
            }

            var data = await q.Where(where).GetPageResultAsync(input);

            var count = data.Total;
            var sList = data.Data;

            List<BTB_StaffUser> cLsit = new List<BTB_StaffUser>();
            foreach (var item in sList)
            {
                var model = new BTB_StaffUser {
                    id = item.id,
                    NickName = item.NickName,
                    RealName = item.RealName,
                    Sex = item.Sex,
                    Serial = item.Serial,
                    HeadPortrait = item.HeadPortrait,
                    HeadType = item.HeadType,
                    phone = item.phone,
                    State = item.State,
                    CreateTime = item.CreateTime,
                    SPState = item.SPState
                };
                cLsit.Add(model);
            };

            var datas = new PageResult<BTB_StaffUser> { 
                Total = count,
                Data = cLsit
            };



            return datas;
        }

        /// <summary>
        /// 获取邀请码
        /// </summary>
        /// <returns></returns>
        public string GetMyYQCode()
        {
            var model = GetEntity(_operator.UserId);
            return model.User_YQCode;
        }

        public async Task UpdateYQCode(ChangeCodeDTO input) {
            var aCount =  GetIQueryable().Where(x => x.User_YQCode.Equals(input.Code)).Count();

            if (aCount > 0)
            {
                var mList = await GetIQueryable().Where(x => x.id.Equals(input.Id)).ToListAsync();
                if (mList.Count > 0)
                {
                    mList[0].User_BYQCode = input.Code;
                    await _db.UpdateAsync(mList[0]);
                }
                else 
                {
                    throw new BusException("未查询到此用户，请重试！");
                }
            }
            else 
            {
                throw new BusException("该邀请码不存在，请重试！");
            }
          
            
        }  

        public BTB_StaffUser GetTheDataAsync()
        {
            var aa = GetIQueryable().Where(q => q.id == _operator.UserId).FirstOrDefault();
            BTB_StaffUser data = new BTB_StaffUser()
            {
                id = aa.id,
                phone = Regex.Replace(aa.phone, "(\\d{3})\\d{4}(\\d{4})", "$1****$2"),
                NickName = aa.NickName,
                RealName = aa.RealName,
                Name = aa.Name,
                HeadType = aa.HeadType,
                Sex = aa.Sex,
                Address = aa.Address,
                Serial = aa.Serial,
                HeadPortrait = aa.HeadPortrait,
            };
            return data;
        }

     
        public string GetEQImgData()
        {

            var url  = ConfigurationUtil.GetSection("Indentity:qrcodeurl");

            var suser = GetEntity(_operator.UserId);

            url += "?YQCode="+ suser.User_YQCode;
            url += "&UName=" + GetMMMString(suser.NickName);
            url += "&HeadUrl=" + suser.User_YQCode;

            return url;

        }

        public string GetXcxEQImgData(string rootPath)
        {
            string imgStr = "";
            var suser = GetEntity(_operator.UserId);
            // string path = "/OutputImg/wx123456.jpg";
            string path = "/OutputImg/wx" + suser.User_YQCode + ".jpg";
            string wPath = rootPath + path;

            CheckFilePath(wPath);

            string dataStr = suser.User_YQCode;
            string page = "pages/register/register";
            string width = "300";

            string app_id = _configsService.GetKeyValue("AppID");
            string appSecret = _configsService.GetKeyValue("AppSecret");

            try
            {
                imgStr = XcxERQcdes.GetXcxQRCodeHelper(wPath, dataStr, page, width, app_id, appSecret);

            }
            catch (Exception ex)
            {
                throw new BusException("生成二维码失败");
            }

            return path;
        }

        /// <summary>
        /// 验证保存路径
        /// </summary>
        /// <param name="savePath"></param>
        static void CheckFilePath(string savePath)
        {
            string ext = string.Empty;
            string path = string.Empty;
            string fileName = string.Empty;

            ext = Path.GetExtension(savePath);
            if (string.IsNullOrEmpty(ext) || (ext.ToLower() != ".jpg" && ext.ToLower() != ".jpeg" && ext.ToLower() != ".png"))
            {
                throw new Exception("文件保存必须是图片格式！");
            }

            fileName = Path.GetFileName(savePath);
            if (string.IsNullOrEmpty(fileName))
            {
                throw new Exception("图片名称不能为空！");
            }

            try
            {
                path = savePath.Substring(0, savePath.IndexOf(fileName));
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
            }
            catch
            {
                throw new Exception("创建目录失败，请检查权限！");
            }
        }

        public BTB_StaffUser GetUserData()
        {
            var suser = GetEntity(_operator.UserId);
            return suser;

        }

        /// <summary>
        /// 返回隐藏中间的字符串
        /// </summary>
        /// <param name="Input">输入</param>
        /// <returns>输出</returns>
        private static string GetMMMString(string Input)
        {
            string Output = "";
            switch (Input.Length)
            {
                case 1:
                    Output = Input;
                    break;
                case 2:
                    Output = Input[0] + "*";
                    break;
                case 0:
                    Output = "";
                    break;
                default:
                    Output = Input.Substring(0, 1);
                    for (int i = 0; i < Input.Length - 2; i++)
                    {
                        Output += "*";
                    }
                    Output += Input.Substring(Input.Length - 1, 1);
                    break;
            }
            return Output;
        }

        public async Task AddDataAsync(BTB_StaffUser data)
        {

            if (data.User_BYQCode.IsNullOrEmpty() || !TestYQCode(data.User_BYQCode))
            {
                //获取默认邀请码
                var sList = GetIQueryable().Where(x => x.IsRoot == true).ToList();
                if (sList.Count > 0)
                {
                    data.User_BYQCode = sList[0].User_YQCode;
                }
                else
                {
                    data.User_BYQCode = "300333";
                }
            }

            int headType = 1;
            string userName = data.NickName, headPortrait = data.HeadPortrait;
            if (data.NickName.IsNullOrEmpty())
            {
                userName = "用户-" + GenerateCheckCode();
            }

            if (data.HeadPortrait.IsNullOrEmpty())
            {
                headPortrait = "/Upload/HeadPort/dhead.jpg";
                headType = 0;
            }

            int userSex = 0;
            if (data.Sex.HasValue)
            {
                userSex = (int)data.Sex;
            }

            Random random = new Random();
            BTB_StaffUser bTB_StaffUser = new BTB_StaffUser()
            {
                id = GuidHelper.GenerateKey(),
                phone = data.phone,
                NickName = userName,
                Sex = userSex,
                HeadType = headType,
                Address = "",
                HeadPortrait = headPortrait,
                Password = data.Password.ToMD5String(),
                User_YQCode = GetYQCode().ToString(),
                User_BYQCode = data.User_BYQCode,
                CreateTime = DateTime.Now,
                EditTime = data.EditTime,
                Serial = GetSRCode(),
                verCode = data.verCode,
                Code = data.Code,
                Openid = data.Openid,
            };

            if (bTB_StaffUser.verCode.ToMD5String() == bTB_StaffUser.Code)
            {
                var user = GetIQueryable().Where(q => q.phone == data.phone).Count();
                if (user <= 0)
                {
                    try
                    {
                        await InsertAsync(bTB_StaffUser);
                    }
                    catch (Exception ex)
                    {
                        throw new BusException("注册失败，请重试", errorCode: -5);
                    }
                }
                else
                {
                    throw new BusException("该手机号已经注册", errorCode: -1);
                }
            }
            else
            {
                throw new BusException("验证码错误", errorCode: -2);
            }
        }


        public async Task SaveSiteInfoAsnyc(SetSiteDTO input)
        {
            var mods = await GetIQueryable().Where(x => x.id.Equals(_operator.UserId)).ToListAsync();
            if (mods.Count > 0 )
            {
                if (!input.Longitude.IsNullOrEmpty())
                {
                    mods[0].Longitude = input.Longitude;
                }

                if (!input.Latitude.IsNullOrEmpty())
                {
                    mods[0].Latitude = input.Latitude;
                }

                await UpdateAsync(mods[0]);
            }
        }

        private string GenerateCheckCode()
        {
            int number;
            string checkCode = String.Empty;     //存放随机码的字符串

            System.Random random = new Random();

            for (int i = 0; i < 6; i++) //产生4位校验码
            {
                number = random.Next();
                number = number % 36;
                if (number < 10)
                {
                    number += 48;    //数字0-9编码在48-57
                }
                else
                {
                    number += 55;    //字母A-Z编码在65-90
                }

                checkCode += ((char)number).ToString();
            }

            return checkCode;
        }

   
        /// <summary>
        /// 生成邀请码
        /// </summary>
        /// <returns></returns>
        private int GetYQCode()
        {
            Random random = new Random();
            int num = random.Next(100000, 999999);
            var sCount = GetIQueryable().Where(x => x.User_YQCode.Equals(num.ToString())).Count();
            if (sCount > 0)
            {
                num = GetYQCode();
            }

            return num;
        }

        /// <summary>
        /// 生成邀请码
        /// </summary>
        /// <returns></returns>
        private int GetSRCode()
        {
            Random random = new Random();
            int num = random.Next(10000000, 99999999);
            var sCount = GetIQueryable().Where(x => x.Serial.Equals(num.ToString())).Count();
            if (sCount > 0)
            {
                num = GetYQCode();
            }

            return num;
        }


        /// <summary>
        /// 忘记密码
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task ForgetPasswordAsync(UserForgetPassword data)
        {
            var users = await GetIQueryable().Where(q => q.phone == data.Phone).ToListAsync();
            if (users.Count > 0)
            {
                if (data.VerCode.ToMD5String() == data.Code)
                {
                    try
                    {
                        var data1 = GetIQueryable().Where(q => q.phone == data.Phone).ToList();
                        data1[0].Password = data.Password.ToMD5String();
                        await UpdateAsync(data1[0]);
                    }
                    catch (Exception ex)
                    {
                        throw new BusException("修改失败，请重试", errorCode: -5);
                    }

                }
                else
                {
                    throw new BusException("验证码错误", errorCode: -1);
                }              
            }
            else
            {
                throw new BusException("该手机号未注册", errorCode: -2);
            }
        }

        /// <summary>
        /// 修改用户状态
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        /// <exception cref="BusException"></exception>
        public async Task SPUserStateAsync(SPUserDTO input)
        {
            var uModel = GetIQueryable().Where(x => x.id.Equals(input.Id)).FirstOrDefault();
            if (uModel.SPState.IsNullOrEmpty())
            {
                throw new BusException("查询用户失败，请重试！");
            }
            else if (uModel.SPState != 1 && input.State == 1)
            {
                uModel.SPState = input.State;
                await UpdateAsync(uModel);
            }
            else if (uModel.SPState != -1 && input.State != 1 && input.State != 0)
            {
                uModel.SPState = -1;
                await UpdateAsync(uModel);
            }
            else
            {
                throw new BusException("传入状态错误，请修改后重试！");
            }

        }

        /// <summary>
        /// 后台——获取用户下拉
        /// </summary>
        /// <returns></returns>
        public async Task<List<SelectDTO>> GetUserListAsync()
        {
            List<SelectDTO> list = new List<SelectDTO>();
            var uList = await GetIQueryable().Where(x => x.SPState == 1).Select(x => new
            {
                x.id,
                x.RealName,
                x.phone
            }).ToListAsync();

            foreach (var item in uList)
            {
                SelectDTO model = new SelectDTO();
                model.Text = item.RealName +"/"+item.phone;
                model.Val = item.id;
                list.Add(model);
            }

            return list;
        }

        /// <summary>
        /// 冻结账号
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task ChangeUserState(IdInputDTO input)
        {
            var model = await GetIQueryable().Where(x =>x.id.Equals(input.Id)).ToListAsync();
            if(model.Count > 0)
            {
                Base_UserLog data = new Base_UserLog();
                data.Id = IdHelper.GetId();
                data.CreateTime = DateTime.Now;
                data.CreatorId = _operator.UserId;
                data.CreatorRealName = _operator.Property.RealName;

                var cache = _serviceProvider.GetService<IDistributedCache>();
                if (model[0].State == -1)
                {
                    model[0].State = 0;
                    data.LogType = "解冻账号";
                    data.LogContent = "解冻账号:" + model[0].phone;

                    //修改状态为解冻状态
                    cache.SetString(input.Id + "123","0");
                }
                else
                {
                    model[0].State = -1;
                    data.LogType = "冻结账号";
                    data.LogContent = "冻结账号:" + model[0].phone;

                    //修改状态为冻结状态
                    cache.SetString(input.Id + "123", "-1");

                }

               await UpdateAsync(model[0]);

               await _db.InsertAsync(data);
            }
        }

        /// <summary>
        /// 修改个人信息
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task UpdateUserAsync(BTB_StaffUser data)
        {
            //var Phone = GetIQueryable().Where(q => q.id == _operator.UserId).FirstOrDefault();
            var data1 = GetIQueryable().Where(q => q.id == _operator.UserId).ToList();


            if (data1.Count > 0)
            {
                if (!data.NickName.IsNullOrEmpty())
                {
                    data1[0].NickName = data.NickName;
                }

                if (!data.RealName.IsNullOrEmpty())
                {
                    data1[0].RealName = data.RealName;
                }

                if (data.Sex.HasValue)
                {
                    data1[0].Sex = data.Sex;
                }

                if (!data.Address.IsNullOrEmpty())
                {
                    data1[0].Address = data.Address;
                }

                if (!data.HeadPortrait.IsNullOrEmpty())
                {
                    if (data.HeadPortrait.IndexOf("http") == 0 || (data.HeadPortrait.IsNullOrEmpty() && data1[0].HeadPortrait.IndexOf("http") == 0))
                    {
                        data1[0].HeadType = 1;
                    }
                    else
                    {
                        data1[0].HeadType = 0;
                    }

                    data1[0].HeadPortrait = data.HeadPortrait;
                }

                if (!data.NickName.IsNullOrEmpty())
                {
                    data1[0].NickName = data.NickName;
                }
                data1[0].RealName = data.RealName;
                data1[0].Sex = data.Sex;
                data1[0].Address = data.Address;
                data1[0].EditTime = DateTime.Now;
                await UpdateAsync(data1[0]);
            }
            else
            {
                throw new BusException("获取个人信息失败，请重新登陆后重试！");
            }
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            var model = GetIQueryable().Where(q => q.id == ids[0]).ToList();
            if (model.Count > 0)
            {
                Base_UserLog data = new Base_UserLog();
                data.Id = IdHelper.GetId();
                data.CreateTime = DateTime.Now;
                data.CreatorId = _operator.UserId;
                data.CreatorRealName = _operator.Property.RealName;
                data.LogType = "删除用户";
                data.LogContent = "删除用户:" + model[0].phone;

                await DeleteAsync(ids);

                await _db.InsertAsync(data);
            }
           
        }

        public async Task<string> PasswordLogin(UserLoginInputDTO input)
        {
            input.password = input.password.ToMD5String();
            var count =  GetIQueryable().Where(x => x.phone == input.userName).Count();
            if (count == 0)
            {
                throw new BusException("该账号未注册，请注册之后重试！",406);
            }

            var count1 = GetIQueryable().Where(x => x.phone == input.userName && x.State == -1).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号已被冻结，无法登陆！", 408);
            }

            var count2 = GetIQueryable().Where(x => x.phone == input.userName && x.SPState == 0).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号在审核中，暂时无法登陆！", 409);
            }

            var count3 = GetIQueryable().Where(x => x.phone == input.userName && x.SPState == -1).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号未通过审核，无法登陆！", 411);
            }

            var theUser = await GetIQueryable()
                .Where(x => x.phone == input.userName && x.Password == input.password && x.SPState == 1)
                .FirstOrDefaultAsync();

            if (theUser.IsNullOrEmpty())
                throw new BusException("账号或密码不正确！");

            //生成token
            //string token = GetTheToken(theUser.id);
            HttpContextAccessor context = new HttpContextAccessor();
            BTB_UserVisit data = new BTB_UserVisit()
            {

                id = GuidHelper.GenerateKey(),
                VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                CreateTime = DateTime.Now,
                Userid = theUser.id,
                Deleted = true
            };

            Service.Insert<BTB_UserVisit>(data);

            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString(theUser.id, theUser.State.ToString());

            return theUser.id;
        }
        public async Task<string> VerificationLogin(LoginInputDTO2 input)
        {
            var count = GetIQueryable().Where(x => x.phone == input.userName).Count();
            if (count == 0)
            {
                throw new BusException("该账号未注册，请注册之后重试！", 406);
            }

            var count1 = GetIQueryable().Where(x => x.phone == input.userName && x.State == -1).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号已被冻结，无法登陆！", 408);
            }

            var count2 = GetIQueryable().Where(x => x.phone == input.userName && x.SPState == 0).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号在审核中，暂时无法登陆！", 409);
            }

            var count3 = GetIQueryable().Where(x => x.phone == input.userName && x.SPState == -1).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号未通过审核，无法登陆！", 411);
            }

            var theUser = await GetIQueryable()
                .Where(x => x.phone == input.userName && x.SPState == 1)
                .FirstOrDefaultAsync();

            if (theUser.IsNullOrEmpty() || input.verCode.ToMD5String() != input.Code)
                throw new BusException("验证码、账号或密码不正确！");

            //生成token
            //string token = GetTheToken(theUser.id);

            HttpContextAccessor context = new HttpContextAccessor();
            BTB_UserVisit data = new BTB_UserVisit()
            {

                id = GuidHelper.GenerateKey(),
                VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                CreateTime = DateTime.Now,
                Userid = theUser.id,
                Deleted = true

            };

            Service.Insert<BTB_UserVisit>(data);

            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString(theUser.id, theUser.State.ToString());

            return theUser.id;
        }


        #region//微信H5公众号OpenId授权登录/注册
        /// <summary>
        /// openId登录，未注册返回Code:-201
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> OpenIdLogin(OpenIdInputDTO input)
        {
            var count1 = GetIQueryable().Where(x => x.Openid == input.OpenId && x.State == -1).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号已被冻结，无法登陆！", 408);
            }

            var theUser = await GetIQueryable()
                .Where(x => x.Openid == input.OpenId)
                .FirstOrDefaultAsync();

            if (theUser.IsNullOrEmpty())
            {
                throw new BusException("此账号未注册！", -201);
            }

            //生成token
            string token = GetTheToken(theUser.id);
            HttpContextAccessor context = new HttpContextAccessor();
            BTB_UserVisit data = new BTB_UserVisit()
            {

                id = GuidHelper.GenerateKey(),
                VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                CreateTime = DateTime.Now,
                Userid = theUser.id,
                Deleted = true
            };
            await Service.InsertAsync(data);

            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString(theUser.id + "123", theUser.State.ToString());

            return token;
        }

        /// <summary>
        /// openId登录，未注册返回Code:-201
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> OpenIdsLogin(OpenIdInputDTO input)
        {
            var count1 = GetIQueryable().Where(x => x.Openid == input.OpenId && x.State == -1).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号已被冻结，无法登陆！", 408);
            }

            var theUser = await GetIQueryable()
                .Where(x => x.Openid == input.OpenId)
                .FirstOrDefaultAsync();

            if (theUser.IsNullOrEmpty())
            {
                return "";
            }

            //生成token
            string token = GetTheToken(theUser.id);
            HttpContextAccessor context = new HttpContextAccessor();
            BTB_UserVisit data = new BTB_UserVisit()
            {

                id = GuidHelper.GenerateKey(),
                VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                CreateTime = DateTime.Now,
                Userid = theUser.id,
                Deleted = true
            };
            await Service.InsertAsync(data);

            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString(theUser.id + "123", theUser.State.ToString());

            return token;
        }

        public async Task<string> OPhoneLogin(OPhoneInputDTO input)
        {
            string token = "";
            if (!input.verCode.IsNullOrEmpty() &&  input.verCode.ToMD5String() == input.Code)
            {
                var count1 = GetIQueryable().Where(x => x.phone == input.Phone && x.State == -1).Count();
                if (count1 > 0)
                {
                    throw new BusException("该账号已被冻结，无法登陆！", 408);
                }

                var theUser = await GetIQueryable()
                .Where(x => x.phone == input.Phone)
                .FirstOrDefaultAsync();
                if (theUser.IsNullOrEmpty())
                {
                    throw new BusException("此账号未注册！", -201);
                }
                else
                {
                    theUser.Openid = input.OpenId;
                    await UpdateAsync(theUser);
                }

                //生成token
                token = GetTheToken(theUser.id);
                HttpContextAccessor context = new HttpContextAccessor();
                BTB_UserVisit data = new BTB_UserVisit()
                {

                    id = GuidHelper.GenerateKey(),
                    VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                    CreateTime = DateTime.Now,
                    Userid = theUser.id,
                    Deleted = true
                };
                await Service.InsertAsync(data);

                var cache = _serviceProvider.GetService<IDistributedCache>();
                cache.SetString(theUser.id + "123", theUser.State.ToString());
            }
            else
            {
                throw new BusException("验证码输入错误，请重试！", -2);
            }

            return token;
        }

        /// <summary>
        /// H5的OpenId授权注册并登录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<string> OpenIdRegistLogin(OpenIdRegistInputDTO data)
        {
            if (data.User_BYQCode.IsNullOrEmpty() || !TestYQCode(data.User_BYQCode))
            {
                //获取默认邀请码
                var sList = GetIQueryable().Where(x => x.IsRoot == true).ToList();
                if (sList.Count > 0)
                {
                    data.User_BYQCode = sList[0].User_YQCode;
                }
                else
                {
                    data.User_BYQCode = "300333";
                }
            }

            var aList = GetIQueryable().Where(x => x.Openid.Equals(data.Openid)).ToList();
            var bList = GetIQueryable().Where(x => x.phone.Equals(data.phone)).ToList();
            BTB_StaffUser bTB_StaffUser = new BTB_StaffUser();
            if (aList.Count > 0)
            {
                bTB_StaffUser = aList[0];
            }
            else if (bList.Count > 0)
            {
                bTB_StaffUser = bList[0];
            }
            else
            {
                if (!data.Openid.IsNullOrEmpty() && !data.access_token.IsNullOrEmpty())
                {
                    //Log.Debug("OpenIdRegistLogin", "获取用户信息开始===》");
                    //Log.Debug("OpenIdRegistLogin", "access_token=" + data.access_token);
                    //Log.Debug("OpenIdRegistLogin", "Openid=" + data.Openid);
                    var suser = GetUserInfo(data.Openid, data.access_token);
                    data.Openid = suser.Openid;
                    data.NickName = suser.NickName;
                    data.RaleName = suser.RealName;
                    data.Sex = suser.Sex;
                    data.Address = suser.Address;
                    data.HeadPortrait = suser.HeadPortrait;
                }


                Random random = new Random();
                int headType = 1;
                if (data.HeadPortrait.IsNullOrEmpty())
                {
                    data.HeadPortrait = "/Upload/HeadPort/dhead.jpg";
                    headType = 0;
                }
                bTB_StaffUser = new BTB_StaffUser()
                {
                    id = GuidHelper.GenerateKey(),
                    phone = data.phone,
                    NickName = data.NickName,
                    HeadType = headType,
                    Sex = data.Sex,
                    Address = data.Address,
                    HeadPortrait = data.HeadPortrait,
                    Password = data.Password.ToMD5String(),
                    User_YQCode = GetYQCode().ToString(),
                    User_BYQCode = data.User_BYQCode,
                    CreateTime = DateTime.Now,
                    EditTime = DateTime.Now,
                    Serial = GetSRCode(),
                    Openid = data.Openid
                };

                try
                {
                    await InsertAsync(bTB_StaffUser);
                }
                catch (Exception ex)
                {
                    throw new BusException("注册失败，请重试", errorCode: -5);
                }
            }

            //生成token
            string token = GetTheToken(bTB_StaffUser.id);
            HttpContextAccessor context = new HttpContextAccessor();
            BTB_UserVisit data1 = new BTB_UserVisit()
            {

                id = GuidHelper.GenerateKey(),
                VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                CreateTime = DateTime.Now,
                Userid = bTB_StaffUser.id,
                Deleted = true
            };
            await Service.InsertAsync(data);

            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString(bTB_StaffUser.id + "123", bTB_StaffUser.State.ToString());

            return token;
        }

        #endregion


        #region//微信小程序OpenId授权登录/注册
        /// <summary>
        /// openId登录，未注册返回Code:-201
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> AppletOpenIdLogin(OpenIdInputDTO input)
        {
            var count1 = GetIQueryable().Where(x => x.AppletOpenId == input.OpenId && x.State == -1).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号已被冻结，无法登陆！", 408);
            }

            var theUser = await GetIQueryable()
                .Where(x => x.AppletOpenId == input.OpenId)
                .FirstOrDefaultAsync();

            if (theUser.IsNullOrEmpty())
            {
                throw new BusException("此账号未注册！", -201);
            }

            //生成token
            string token = GetTheToken(theUser.id);
            HttpContextAccessor context = new HttpContextAccessor();
            BTB_UserVisit data = new BTB_UserVisit()
            {

                id = GuidHelper.GenerateKey(),
                VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                CreateTime = DateTime.Now,
                Userid = theUser.id,
                Deleted = true
            };
            await Service.InsertAsync(data);

            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString(theUser.id + "123", theUser.State.ToString());

            return token;
        }

        /// <summary>
        /// openId登录，未注册返回Code:-201
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<string> AppletOpenIdsLogin(OpenIdInputDTO input)
        {
            var count1 = GetIQueryable().Where(x => x.AppletOpenId == input.OpenId && x.State == -1).Count();
            if (count1 > 0)
            {
                throw new BusException("该账号已被冻结，无法登陆！", 408);
            }

            var theUser = await GetIQueryable()
                .Where(x => x.AppletOpenId == input.OpenId)
                .FirstOrDefaultAsync();

            if (theUser.IsNullOrEmpty())
            {
                return "";
            }

            //生成token
            string token = GetTheToken(theUser.id);
            HttpContextAccessor context = new HttpContextAccessor();
            BTB_UserVisit data = new BTB_UserVisit()
            {

                id = GuidHelper.GenerateKey(),
                VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                CreateTime = DateTime.Now,
                Userid = theUser.id,
                Deleted = true
            };
            await Service.InsertAsync(data);

            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString(theUser.id + "123", theUser.State.ToString());

            return token;
        }

        public async Task<string> AppletOPhoneLogin(OPhoneInputDTO input)
        {
            string token = "";
            if (!input.verCode.IsNullOrEmpty() && input.verCode.ToMD5String() == input.Code)
            {
                var count1 = GetIQueryable().Where(x => x.phone == input.Phone && x.State == -1).Count();
                if (count1 > 0)
                {
                    throw new BusException("该账号已被冻结，无法登陆！", 408);
                }

                var theUser = await GetIQueryable()
                .Where(x => x.phone == input.Phone)
                .FirstOrDefaultAsync();
                if (theUser.IsNullOrEmpty())
                {
                    return "";
                }
                else
                {
                    theUser.AppletOpenId = input.OpenId;
                    await UpdateAsync(theUser);
                }

                //生成token
                token = GetTheToken(theUser.id);
                HttpContextAccessor context = new HttpContextAccessor();
                BTB_UserVisit data = new BTB_UserVisit()
                {

                    id = GuidHelper.GenerateKey(),
                    VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                    CreateTime = DateTime.Now,
                    Userid = theUser.id,
                    Deleted = true
                };
                await Service.InsertAsync(data);

                var cache = _serviceProvider.GetService<IDistributedCache>();
                cache.SetString(theUser.id + "123", theUser.State.ToString());
            }
            else
            {
                throw new BusException("验证码输入错误，请重试！", -2);
            }

            return token;
        }

        /// <summary>
        /// H5的OpenId授权注册并登录
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public async Task<string> AppletOpenIdRegistLogin(OpenIdRegistInputDTO data)
        {
            if (data.User_BYQCode.IsNullOrEmpty() || !TestYQCode(data.User_BYQCode))
            {
                //获取默认邀请码
                var sList = GetIQueryable().Where(x => x.IsRoot == true).ToList();
                if (sList.Count > 0)
                {
                    data.User_BYQCode = sList[0].User_YQCode;
                }
                else
                {
                    data.User_BYQCode = "300333";
                }
            }

            var aList = GetIQueryable().Where(x => x.AppletOpenId.Equals(data.Openid)).ToList();
            var bList = GetIQueryable().Where(x => x.phone.Equals(data.phone)).ToList();
            BTB_StaffUser bTB_StaffUser = new BTB_StaffUser();
            if (aList.Count > 0)
            {
                bTB_StaffUser = aList[0];
            }
            else if (bList.Count > 0)
            {
                bTB_StaffUser = bList[0];
            }
            else
            {
                Random random = new Random();
                int headType = 1;
                if (data.HeadPortrait.IsNullOrEmpty())
                {
                    data.HeadPortrait = "/Upload/HeadPort/dhead.jpg";
                    headType = 0;
                }
                bTB_StaffUser = new BTB_StaffUser()
                {
                    id = GuidHelper.GenerateKey(),
                    phone = data.phone,
                    NickName = data.NickName,
                    HeadType = headType,
                    Sex = data.Sex,
                    Address = data.Address,
                    HeadPortrait = data.HeadPortrait,
                    Password = data.Password.ToMD5String(),
                    User_YQCode = GetYQCode().ToString(),
                    User_BYQCode = data.User_BYQCode,
                    CreateTime = DateTime.Now,
                    EditTime = DateTime.Now,
                    Serial = GetSRCode(),
                    AppletOpenId = data.Openid
                };

                try
                {
                    await InsertAsync(bTB_StaffUser);
                }
                catch (Exception ex)
                {
                    throw new BusException("注册失败，请重试", errorCode: -5);
                }
            }

            //生成token
            string token = GetTheToken(bTB_StaffUser.id);
            HttpContextAccessor context = new HttpContextAccessor();
            BTB_UserVisit data1 = new BTB_UserVisit()
            {

                id = GuidHelper.GenerateKey(),
                VisitIP = context.HttpContext?.Connection.RemoteIpAddress.ToString(),
                CreateTime = DateTime.Now,
                Userid = bTB_StaffUser.id,
                Deleted = true
            };
            await Service.InsertAsync(data);

            var cache = _serviceProvider.GetService<IDistributedCache>();
            cache.SetString(bTB_StaffUser.id + "123", bTB_StaffUser.State.ToString());

            return token;
        }

        #endregion
        #endregion



        private string GetTheToken(string userId, int day = 30)
        {
            //生成token,有效期一天
            JWTPayload jWTPayload = new JWTPayload
            {
                UserId = userId,
                Expire = DateTime.Now.AddDays(day)
            };
            string token = JWTHelper.GetToken(jWTPayload.ToJson(), JWTHelper.FrontSecret);

            return token;
        }

        public string GetOpenId(User user)
        {

            JObject Data = new JObject();
            string app_id = _configsService.GetKeyValue("AppID");
            string appSecret = _configsService.GetKeyValue("AppSecret");

            Data = wxGetOpenid.Getopenid(app_id, appSecret, user.Codes);
            string openID = Data["openid"].ToString();

          
            return openID;
        }

        public async Task<string> SaveData(User user)
        {

            JObject Data = new JObject();
            string app_id = _configsService.GetKeyValue("AppID");
            string appSecret = _configsService.GetKeyValue("AppSecret");
            Data = wxGetOpenid.Getopenid(app_id, appSecret, user.Codes);
            string openID = Data["openid"].ToString();
            //TLSSigAPIv2 api = new TLSSigAPIv2(1400411874, "4b10844d843d8702dd2866898118e5584b7babe264666960c1fbb3d11702328c");

            var data = GetIQueryable().Where(q => q.phone == user.Phone).ToList();
            if (data.Count() < 0)
            {
                throw new BusException("账号出现异常，请联系管理员", errorCode: -1);
            }
            data[0].Openid = openID;
            await _db.UpdateAsync<BTB_StaffUser>(data[0]);
            return openID;
        }

        public async Task<string> SaveGZHData(User user)
        {

            JObject Data = new JObject();
            string app_id = _configsService.GetKeyValue("OAppID");
            string appSecret = _configsService.GetKeyValue("OAppSecret");
            Data = wxGetOpenid.GetWebopenid(app_id, appSecret, user.Codes);
            string openID = Data["openid"].ToString();
            string access_token = Data["access_token"].ToString();

            //TLSSigAPIv2 api = new TLSSigAPIv2(1400411874, "4b10844d843d8702dd2866898118e5584b7babe264666960c1fbb3d11702328c");

            if (!user.Phone.IsNullOrEmpty())
            {
                var data = GetIQueryable().Where(q => q.phone == user.Phone).ToList();
                if (data.Count() < 0)
                {
                    throw new BusException("账号出现异常，请联系管理员", errorCode: -1);
                }
                data[0].Openid = openID;
                await _db.UpdateAsync<BTB_StaffUser>(data[0]);
            }


            var str = "openid=" + openID + "&access_token=" + access_token;

            return str;
        }

        public BTB_StaffUser GetUserInfo(string openId, string access_token)
        {
            BTB_StaffUser user = new BTB_StaffUser();
            JObject Data = new JObject();
            string app_id = _configsService.GetKeyValue("OAppID");
            string appSecret = _configsService.GetKeyValue("OAppSecret");
            Data = wxGetOpenid.GetUserInfo(app_id, appSecret, openId, access_token);
            if (!Data.IsNullOrEmpty())
            {
                user.Openid = Data["openid"].ToString();
                user.NickName = Data["nickname"].ToString();
                int? sex = null;
                if (!Data["sex"].IsNullOrEmpty())
                {
                    sex = int.Parse(Data["sex"].ToString());
                }
                user.Sex = sex;

                string address = "";
                if (!Data["province"].IsNullOrEmpty())
                {
                    address = Data["province"].ToString();
                }
                if (!Data["city"].IsNullOrEmpty())
                {
                    address = address + Data["city"].ToString();
                }
                user.Address = address;
                if (!Data["headimgurl"].IsNullOrEmpty())
                {
                    user.HeadPortrait = Data["headimgurl"].ToString();
                }
            }

            return user;
        }

        /// <summary>
        /// 授权获取assentionToken
        /// </summary>
        /// <returns></returns>
        public object GetAssetToken()
        {
            var accesstoken = new object();
            try
            {
                string appId = _configsService.GetKeyValue("OAppID");
                string secret = _configsService.GetKeyValue("OAppSecret");

                string str1 = wxGetOpenid.HttpGet($"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={secret}");

                if (str1.Contains("access_token"))
                {
                    JObject Jobj = (JObject)JsonConvert.DeserializeObject(str1);
                    string str2 = Jobj.Value<string>("access_token");
                    int num = Jobj.Value<int>("expires_in") / 2;

                    accesstoken = new {
                        Token = str2,
                        ExpiresTime = DateTime.Now.AddSeconds((double)num)
                    };

                    return accesstoken;
                }

            }
            catch (Exception e)
            {
                throw new BusException("生成AccessToken出错:" + e.Message,-302);
            }

            return accesstoken;

        }

        public PDiagramDTO GetMyDiagram(GetDiagramInput input)
        {
            string userId = input.UserId;
            PDiagramDTO uModel = new PDiagramDTO();
            try 
            {
                if (userId.IsNullOrEmpty())
                {
                    userId = _operator.UserId;
                }
                string pId = "";
                var myInfo = GetEntity(userId);
                if (!myInfo.User_BYQCode.IsNullOrEmpty() && !userId.Equals(_operator.UserId))
                {
                    var smList = GetIQueryable().Where(x => x.User_YQCode.Equals(myInfo.User_BYQCode)).ToList();
                    if (smList.Count > 0)
                    {
                        pId = smList[0].id;
                    }
                }
                var cList = GetIQueryable().Where(x => x.User_BYQCode.Equals(myInfo.User_YQCode)).ToList();
                List<DiagramDTO> coList = new List<DiagramDTO>();
                foreach (var item in cList)
                {
                    var obj = new DiagramDTO
                    {
                        Id = item.id,
                        NickName = item.NickName,
                        RaleName = item.RealName,
                        Phone = item.phone,
                        HeadImg = item.HeadPortrait,
                        JoinTime = item.CreateTime,
                        HType = item.HeadType,
                        UserCount = GetIQueryable().Where(x => x.User_BYQCode.Equals(item.User_YQCode)).Count()
                    };
                    coList.Add(obj);
                }

                uModel = new PDiagramDTO
                {
                    Id = myInfo.id,
                    ParentId = pId,
                    NickName = myInfo.NickName,
                    RaleName = myInfo.RealName,
                    Phone = myInfo.phone,
                    HeadImg = myInfo.HeadPortrait,
                    JoinTime = myInfo.CreateTime,
                    HType = myInfo.HeadType,
                    Code = myInfo.Serial,
                    UserCount = coList.Count,
                    Childs = coList
                };
            }
            catch
            {
                throw new BusException("个人信息获取失败，关系获取失败！", -3);
            }
      
            return uModel;
        }

        /// <summary>
        /// 返回隐藏中间的字符串
        /// </summary>
        /// <param name="Input">输入</param>
        /// <returns>输出</returns>
        private static string GetMMString(string Input)
        {
            string Output = "";
            switch (Input.Length)
            {
                case 1:
                    Output = Input;
                    break;
                case 2:
                    Output = Input[0] + "*";
                    break;
                case 0:
                    Output = "";
                    break;
                default:
                    Output = Input.Substring(0, 1);
                    for (int i = 0; i < Input.Length - 2; i++)
                    {
                        Output += "*";
                    }
                    Output += Input.Substring(Input.Length - 1, 1);
                    break;
            }
            return Output;
        }

        #region 用SHA1加密字符串

        /// <summary>
        /// 用SHA1加密字符串
        /// </summary>
        /// <param name="strSource">是否把加密后的字符串转小写</param>
        /// <returns></returns>
        private static string SHA1Encrypt(string strSource)
        {
            string strResult = "";

            //Create 
            System.Security.Cryptography.SHA1 md5 = System.Security.Cryptography.SHA1.Create();

            //注意编码UTF8、UTF7、Unicode等的选择 
            byte[] bytResult = md5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(strSource));

            //字节类型的数组转换为字符串 
            for (int i = 0; i < bytResult.Length; i++)
            {
                //16进制转换 
                strResult = strResult + bytResult[i].ToString("X");
            }
            return strResult.ToLower();
        }

        #endregion

        #region 私有成员
        /// <summary>
        /// 验证邀请码
        /// </summary>
        /// <param name="code"></param>
        /// <returns></returns>
        private bool TestYQCode(string code)
        {
            bool theF = false;
            var sCount = GetIQueryable().Where(x => x.User_YQCode.Equals(code)).Count();
            if (sCount > 0)
            {
                theF = true;
            }

            return theF;
        }
        #endregion
    }


}
